﻿using System;
using System.Collections;
using System.Collections.Generic;
using WatiN.Core;
using System.Text.RegularExpressions;
using WatiN.Core.Interfaces;
using AttributeConstraint=WatiN.Core.Constraints.AttributeConstraint;

namespace WatiNCF
{
    public static class WatinFind
    {
        /// <summary>
        /// Gets an attribute constraint using a partial id.
        /// </summary>
        /// <param name="partialElementId">The partial element id.</param>
        /// <returns></returns>
        public static AttributeConstraint ByPartialId(string partialElementId)
        {
            return Find.ById(new Regex(".*" + partialElementId + "$"));
        }



        public static T FindByText<T>(this IElementsContainer target, string text)
            where T : Element
        {
            // Replace open and close brackets with \( and \) so that these can be included in grouping
            text = text.Replace("(", "\\(");
            text = text.Replace(")", "\\)");

            Regex regex = new Regex(string.Concat("(", text, ")"));
            return FindByText<T>(target, regex);
        }

        public  static T FindByText<T>(this IElementsContainer target, Regex regEx) 
            where T : Element
        {
            Type elementType = typeof (T);
            Type targetType = target.GetType();
            
            var result = default(T);
            // Get the name of the property by pluralising the type name
            var property = targetType.GetProperty(string.Concat(elementType.Name, "s"));
            if (property != null)
            {
                var elements = (IEnumerable) property.GetValue(target, null);
                if (elements != null)
                {
                    foreach (T element in elements)
                    {
                        if (element.Text != null)
                        {
                            if (regEx.IsMatch(element.Text.Trim()))
                            {
                                result = element;
                            }
                        }
                    }
                }
            }
            else
            {
                throw new NotSupportedException(string.Format(
                                                    "Element type {0} is not supported on the object type {1}",
                                                    elementType.Name, targetType.Name));
            }
            return result;
        }
    }
}